/**
 * 用户行为追踪器
 * 记录用户操作路径，帮助复现问题
 */

import type { UserBehaviorData } from '~/types/monitor';
import { ConfigManager } from './config-manager';

export class BehaviorTracker {
  private behaviors: UserBehaviorData[] = [];
  private maxBehaviors: number = 50;
  private configManager: ConfigManager;
  private listeners: Array<() => void> = [];

  constructor() {
    this.configManager = ConfigManager.getInstance();

    if (this.configManager.getConfig().enableUserBehavior) {
      this.initTracking();
    }
  }

  /**
   * 初始化行为追踪
   */
  private initTracking(): void {
    this.trackClicks();
    this.trackScrolls();
    this.trackInputs();
    this.trackNavigation();
  }

  /**
   * 追踪点击事件
   */
  private trackClicks(): void {
    const clickHandler = (event: MouseEvent) => {
      const target = event.target as HTMLElement;
      if (!target) return;

      const selector = this.getElementSelector(target);
      this.addBehavior({
        type: 'click',
        target: selector,
        timestamp: Date.now(),
        path: window.location.pathname,
      });
    };

    document.addEventListener('click', clickHandler, true);
    this.listeners.push(() => {
      document.removeEventListener('click', clickHandler, true);
    });
  }

  /**
   * 追踪滚动事件
   */
  private trackScrolls(): void {
    let scrollTimer: NodeJS.Timeout;

    const scrollHandler = () => {
      clearTimeout(scrollTimer);
      scrollTimer = setTimeout(() => {
        this.addBehavior({
          type: 'scroll',
          value: `${window.scrollY}`,
          timestamp: Date.now(),
          path: window.location.pathname,
        });
      }, 200); // 防抖200ms
    };

    window.addEventListener('scroll', scrollHandler, { passive: true });
    this.listeners.push(() => {
      window.removeEventListener('scroll', scrollHandler);
      clearTimeout(scrollTimer);
    });
  }

  /**
   * 追踪输入事件
   */
  private trackInputs(): void {
    const inputHandler = (event: Event) => {
      const target = event.target as HTMLInputElement;
      if (
        !target ||
        !['INPUT', 'TEXTAREA', 'SELECT'].includes(target.tagName)
      ) {
        return;
      }

      const selector = this.getElementSelector(target);
      // 不记录敏感信息，只记录输入类型
      this.addBehavior({
        type: 'input',
        target: selector,
        value: target.type || 'text',
        timestamp: Date.now(),
        path: window.location.pathname,
      });
    };

    document.addEventListener('input', inputHandler, true);
    this.listeners.push(() => {
      document.removeEventListener('input', inputHandler, true);
    });
  }

  /**
   * 追踪页面导航
   */
  private trackNavigation(): void {
    // 记录初始页面
    this.addBehavior({
      type: 'navigation',
      target: 'page_load',
      timestamp: Date.now(),
      path: window.location.pathname,
    });

    // 监听路由变化（适用于SPA）
    const originalPushState = history.pushState;
    const originalReplaceState = history.replaceState;

    history.pushState = function (...args) {
      originalPushState.apply(history, args);
      setTimeout(() => {
        window.dispatchEvent(new Event('locationchange'));
      }, 0);
    };

    history.replaceState = function (...args) {
      originalReplaceState.apply(history, args);
      setTimeout(() => {
        window.dispatchEvent(new Event('locationchange'));
      }, 0);
    };

    const locationChangeHandler = () => {
      this.addBehavior({
        type: 'navigation',
        target: 'route_change',
        timestamp: Date.now(),
        path: window.location.pathname,
      });
    };

    window.addEventListener('popstate', locationChangeHandler);
    window.addEventListener('locationchange', locationChangeHandler);

    this.listeners.push(() => {
      window.removeEventListener('popstate', locationChangeHandler);
      window.removeEventListener('locationchange', locationChangeHandler);
      history.pushState = originalPushState;
      history.replaceState = originalReplaceState;
    });
  }

  /**
   * 获取元素选择器
   */
  private getElementSelector(element: HTMLElement): string {
    if (element.id) {
      return `#${element.id}`;
    }

    if (element.className) {
      const classes = element.className.split(' ').filter(c => c.trim());
      if (classes.length > 0) {
        return `.${classes[0]}`;
      }
    }

    const tagName = element.tagName.toLowerCase();
    const parent = element.parentElement;

    if (parent) {
      const siblings = Array.from(parent.children);
      const index = siblings.indexOf(element);
      return `${tagName}:nth-child(${index + 1})`;
    }

    return tagName;
  }

  /**
   * 添加行为记录
   */
  private addBehavior(behavior: UserBehaviorData): void {
    this.behaviors.push(behavior);

    // 保持最大数量限制
    if (this.behaviors.length > this.maxBehaviors) {
      this.behaviors.shift();
    }
  }

  /**
   * 获取最近的行为记录
   */
  getRecentBehaviors(count: number = 10): UserBehaviorData[] {
    return this.behaviors.slice(-count);
  }

  /**
   * 获取所有行为记录
   */
  getAllBehaviors(): UserBehaviorData[] {
    return [...this.behaviors];
  }

  /**
   * 清空行为记录
   */
  clear(): void {
    this.behaviors = [];
  }

  /**
   * 销毁追踪器
   */
  destroy(): void {
    this.listeners.forEach(cleanup => cleanup());
    this.listeners = [];
    this.clear();
  }
}
